simplify conversion from utm. (#275)
authortsteven4 <tsteven4@users.noreply.github.com>
Tue, 27 Nov 2018 23:37:49 +0000 (16:37 -0700)
committerGitHub <noreply@github.com>
Tue, 27 Nov 2018 23:37:49 +0000 (16:37 -0700)
* simplify conversion from utm.

add test cases for Norway and Svalbard exceptions.

* Correct bug in computing latitude band X.

enhance test to cover exceptional width of band X.

jeeps/gpsmath.cc
reference/grid-utm.csv
reference/grid-utm~csv.gpx
reference/grid-utm~xscv.gpx

index 944fec10dce1430ae7356eb087ce084a6cd07c44..b71654ae5ed46687a467d4d572798206295d463b 100644 (file)
@@ -2004,19 +2004,19 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32* zone,
 {
   int32 ilon;
   int32 ilat;
-  int32 psign;
-  int32 lsign;
+  bool psign;
+  bool lsign;
 
   if (lat >= 84.0 || lat < -80.0) {
     return 0;
   }
 
-  psign = lsign = 0;
+  psign = lsign = false;
   if (lon < 0.0) {
-    lsign=1;
+    lsign=true;
   }
   if (lat < 0.0) {
-    psign=1;
+    psign=true;
   }
 
   ilon = abs((int32)lon);
@@ -2024,10 +2024,10 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32* zone,
 
   if (!lsign) {
     *zone = 31 + (ilon / 6);
-    *Mc   = (double)((ilon / 6) * 6 + 3);
+    *Mc   = static_cast<double>((ilon / 6) * 6 + 3);
   } else {
     *zone = 30 - (ilon / 6);
-    *Mc   = -(double)((ilon / 6) * 6 + 3);
+    *Mc   = -static_cast<double>((ilon / 6) * 6 + 3);
   }
 
   if (!psign) {
@@ -2042,14 +2042,19 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32* zone,
     }
   }
 
+  // The northernmost latitude band, X, is 12 degrees tall
+  // instead of the usual 8 degrees, i.e. [72.0,84.0).
+  if (*zc=='Y') {
+    *zc = 'X';
+  }
 
-  if (lat>=56.0 && lat<64.0 && lon>=3.0 &&
-      lon<12.0) {
+  // Norway exception
+  if (*zc=='V' && lon>=3.0 && lon<12.0) {
     *zone = 32;
-    *zc   = 'V';
     *Mc   = 9.0;
   }
 
+  // Svalbard exception
   if (*zc=='X' && lon>=0.0 && lon<42.0) {
     if (lon<9.0) {
       *zone = 31;
@@ -2169,32 +2174,14 @@ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double* Mc,
                                       double* E0, double* N0, double* F0)
 {
 
-  if (zone>60 || zone<0 || zc<'C' || zc>'X') {
+  if (zone>60 || zone<0 || zc<'C' || zc>'X' || zc=='I' || zc=='O') {
     return 0;
   }
 
-  if (zone > 30) {
-    *Mc = (double)((zone-31)*6) + 3.0;
-  } else {
-    *Mc = (double) -(((30-zone)*6)+3);
-  }
-
-  if (zone==32 && zc=='V') {
-    *Mc = 9.0;
-  }
+  *Mc = static_cast<double>(((zone-31)*6) + 3);
 
-  if (zone==31 && zc=='X') {
-    *Mc = 3.0;
-  }
-  if (zone==33 && zc=='X') {
-    *Mc = 15.0;
-  }
-  if (zone==35 && zc=='X') {
-    *Mc = 27.0;
-  }
-  if (zone==37 && zc=='X') {
-    *Mc = 39.0;
-  }
+  // The Norway and Svalbard exceptions do NOT change the central meridian of
+  // the impacted zones (31V, 32V, 31X, 33X, 35X, 37X).
 
   if (zc>'M') {
     *N0 = 0.0;
index 19d736ac6c1525d872acb75240c261fbb55ebbf2..657b4696fcdf2420c945b89cd92803dda95827b6 100644 (file)
@@ -24,3 +24,17 @@ No,UTM-Zone,UTM-Ch,UTM-East,UTM-North,Name,Altitude,Symbol,Date,Time
 23,29,K,268668,7620784,"Wpt_tzplq3SA",13.0,"Waypoint",2008/08/23,18:15:08\r
 24,57,S,456928,3682270,"Wpt_vhagfqH",10.0,"Waypoint",2008/08/23,18:14:24\r
 25,40,V,590806,6323254,"Wpt_ZHNuvzhQ",51.0,"Waypoint",2008/08/23,18:15:42\r
+26,31,V,388456,6653097,"Wpt_31V_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+27,31,V,444224,6651833,"Wpt_31V_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+28,32,V,221289,6661953,"Wpt_32V_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+29,32,V,611544,6653097,"Wpt_32V_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+30,31,X,446000,8436100,"Wpt_31X_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+31,31,X,634874,8440900,"Wpt_31X_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+32,33,X,365126,8440900,"Wpt_33X_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+33,33,X,634874,8440900,"Wpt_33X_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+34,35,X,365126,8440900,"Wpt_35X_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+35,35,X,634874,8440900,"Wpt_35X_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+36,37,X,365126,8440900,"Wpt_37X_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+37,37,X,554000,8436100,"Wpt_37X_2",0.0,"Waypoint",2018/11/24,00:00:00\r
+38,31,X,457406,8770704,"Wpt_31X_1",0.0,"Waypoint",2018/11/24,00:00:00\r
+39,31,X,472793,9216930,"Wpt_31X_2",0.0,"Waypoint",2018/11/24,00:00:00\r
index 9bfc263cb10ee50e4b91dd7f8e90fc9889ebb109..37c6cc9021e56a189a1fe06dbfe04deff3e3cf70 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
   <time>1970-01-01T00:00:00Z</time>
-  <bounds minlat="-69.883348956" minlon="-172.920053269" maxlat="65.469335178" maxlon="158.537464649"/>
+  <bounds minlat="-69.883348956" minlon="-172.920053269" maxlat="82.999996519" maxlon="158.537464649"/>
   <wpt lat="25.400181298" lon="80.144525617">
     <time>2008-08-23T18:14:04Z</time>
     <name>Wpt_12E7vrv</name>
     <desc>Wpt_ZHNuvzhQ</desc>
     <sym>Waypoint</sym>
   </wpt>
+  <wpt lat="59.999996103" lon="1.000000988">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31V_1</name>
+    <cmt>Wpt_31V_1</cmt>
+    <desc>Wpt_31V_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="60.000002409" lon="2.000004710">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31V_2</name>
+    <cmt>Wpt_31V_2</cmt>
+    <desc>Wpt_31V_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="59.999999787" lon="4.000003927">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_32V_1</name>
+    <cmt>Wpt_32V_1</cmt>
+    <desc>Wpt_32V_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="59.999996103" lon="10.999999012">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_32V_2</name>
+    <cmt>Wpt_32V_2</cmt>
+    <desc>Wpt_32V_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000000478" lon="1.000017959">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31X_1</name>
+    <cmt>Wpt_31X_1</cmt>
+    <desc>Wpt_31X_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="7.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31X_2</name>
+    <cmt>Wpt_31X_2</cmt>
+    <desc>Wpt_31X_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="10.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_33X_1</name>
+    <cmt>Wpt_33X_1</cmt>
+    <desc>Wpt_33X_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="19.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_33X_2</name>
+    <cmt>Wpt_33X_2</cmt>
+    <desc>Wpt_33X_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="22.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_35X_1</name>
+    <cmt>Wpt_35X_1</cmt>
+    <desc>Wpt_35X_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="31.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_35X_2</name>
+    <cmt>Wpt_35X_2</cmt>
+    <desc>Wpt_35X_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000003614" lon="34.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_37X_1</name>
+    <cmt>Wpt_37X_1</cmt>
+    <desc>Wpt_37X_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="76.000000478" lon="40.999982041">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_37X_2</name>
+    <cmt>Wpt_37X_2</cmt>
+    <desc>Wpt_37X_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="79.000001449" lon="1.000006060">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31X_1</name>
+    <cmt>Wpt_31X_1</cmt>
+    <desc>Wpt_31X_1</desc>
+    <sym>Waypoint</sym>
+  </wpt>
+  <wpt lat="82.999996519" lon="0.999966472">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>Wpt_31X_2</name>
+    <cmt>Wpt_31X_2</cmt>
+    <desc>Wpt_31X_2</desc>
+    <sym>Waypoint</sym>
+  </wpt>
 </gpx>
index 6f8a86fbfd152e23dc07e933db6045ceaa6554ac..f62f860c9135ce5db4c8f491a7cc5df4ff8de0ff 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
   <time>1970-01-01T00:00:00Z</time>
-  <bounds minlat="-69.883348956" minlon="-172.920053269" maxlat="65.469335178" maxlon="158.537464649"/>
+  <bounds minlat="-69.883348956" minlon="-172.920053269" maxlat="82.999996519" maxlon="158.537464649"/>
   <wpt lat="25.400181298" lon="80.144525617">
     <time>2008-08-23T18:14:04Z</time>
     <name>&quot;Wpt_12E7vrv&quot;</name>
     <cmt>&quot;Wpt_ZHNuvzhQ&quot;</cmt>
     <desc>&quot;Wpt_ZHNuvzhQ&quot;</desc>
   </wpt>
+  <wpt lat="59.999996103" lon="1.000000988">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31V_1&quot;</name>
+    <cmt>&quot;Wpt_31V_1&quot;</cmt>
+    <desc>&quot;Wpt_31V_1&quot;</desc>
+  </wpt>
+  <wpt lat="60.000002409" lon="2.000004710">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31V_2&quot;</name>
+    <cmt>&quot;Wpt_31V_2&quot;</cmt>
+    <desc>&quot;Wpt_31V_2&quot;</desc>
+  </wpt>
+  <wpt lat="59.999999787" lon="4.000003927">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_32V_1&quot;</name>
+    <cmt>&quot;Wpt_32V_1&quot;</cmt>
+    <desc>&quot;Wpt_32V_1&quot;</desc>
+  </wpt>
+  <wpt lat="59.999996103" lon="10.999999012">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_32V_2&quot;</name>
+    <cmt>&quot;Wpt_32V_2&quot;</cmt>
+    <desc>&quot;Wpt_32V_2&quot;</desc>
+  </wpt>
+  <wpt lat="76.000000478" lon="1.000017959">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31X_1&quot;</name>
+    <cmt>&quot;Wpt_31X_1&quot;</cmt>
+    <desc>&quot;Wpt_31X_1&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="7.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31X_2&quot;</name>
+    <cmt>&quot;Wpt_31X_2&quot;</cmt>
+    <desc>&quot;Wpt_31X_2&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="10.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_33X_1&quot;</name>
+    <cmt>&quot;Wpt_33X_1&quot;</cmt>
+    <desc>&quot;Wpt_33X_1&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="19.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_33X_2&quot;</name>
+    <cmt>&quot;Wpt_33X_2&quot;</cmt>
+    <desc>&quot;Wpt_33X_2&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="22.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_35X_1&quot;</name>
+    <cmt>&quot;Wpt_35X_1&quot;</cmt>
+    <desc>&quot;Wpt_35X_1&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="31.999997628">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_35X_2&quot;</name>
+    <cmt>&quot;Wpt_35X_2&quot;</cmt>
+    <desc>&quot;Wpt_35X_2&quot;</desc>
+  </wpt>
+  <wpt lat="76.000003614" lon="34.000002372">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_37X_1&quot;</name>
+    <cmt>&quot;Wpt_37X_1&quot;</cmt>
+    <desc>&quot;Wpt_37X_1&quot;</desc>
+  </wpt>
+  <wpt lat="76.000000478" lon="40.999982041">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_37X_2&quot;</name>
+    <cmt>&quot;Wpt_37X_2&quot;</cmt>
+    <desc>&quot;Wpt_37X_2&quot;</desc>
+  </wpt>
+  <wpt lat="79.000001449" lon="1.000006060">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31X_1&quot;</name>
+    <cmt>&quot;Wpt_31X_1&quot;</cmt>
+    <desc>&quot;Wpt_31X_1&quot;</desc>
+  </wpt>
+  <wpt lat="82.999996519" lon="0.999966472">
+    <ele>0.000</ele>
+    <time>2018-11-24T00:00:00Z</time>
+    <name>&quot;Wpt_31X_2&quot;</name>
+    <cmt>&quot;Wpt_31X_2&quot;</cmt>
+    <desc>&quot;Wpt_31X_2&quot;</desc>
+  </wpt>
 </gpx>